﻿using Playnite.Common;
using Playnite.SDK;
using Playnite.SDK.Data;
using Playnite.SDK.Models;
using Playnite.SDK.Plugins;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Markup;

namespace LocalGameLibrary
{
    public class LocalGameController : InstallController
    {
        private CancellationTokenSource watcherToken;
        private readonly LocalGameLibrary library;
        private LocalGameMetadata installingGameMetadata;
        private LocalGameLibrarySettingsViewModel settingViewModel;

        public LocalGameController(Game game, LocalGameLibrary library) : base(game)
        {
            this.library = library;
            this.installingGameMetadata = library.LocalGameMetadataDict[this.Game.GetPid()];
            this.settingViewModel = library.GetSettings(true) as LocalGameLibrarySettingsViewModel;
        }

        public override void Dispose()
        {
            watcherToken?.Cancel();
        }

        public override void Install(InstallActionArgs args)
        {
            String pid = this.Game.GetPid();
            if (!String.IsNullOrEmpty(pid))
            {
                if (!String.IsNullOrEmpty(this.installingGameMetadata.SetupExec))
                {
                    var installationCmd = Path.Combine(this.installingGameMetadata.RepoPath, this.installingGameMetadata.SetupExec);
                    ProcessStarter.StartProcess(installationCmd, "", true);
                }
                else
                {
                    System.Diagnostics.Process.Start("Explorer.exe", this.installingGameMetadata.RepoPath);
                }
                StartInstallWatcher();
            }
        }

        /// <summary>
        /// 首先是获取游戏的安装目录即installFolderName，会尝试从安装包目录的metadata中获取，如果没有则从playnite的Notes中提取，
        /// 这里因为游戏的安装目录确实不属于游戏本质属性，属于用户定义数据，因此一般来说是定义在playnite的Notes中的。
        /// </summary>
        public async void StartInstallWatcher()
        {
            watcherToken = new CancellationTokenSource();
            await Task.Run(async () =>
            {
                while (true)
                {
                    if (watcherToken.IsCancellationRequested)
                    {
                        return;
                    }

                    var libRoot = settingViewModel.Settings.LibraryRoot;

                    string installFolderName = this.Game.GetInstallFolderName();
                    if (!String.IsNullOrEmpty(installFolderName))
                    {
                        var installedGameFolderPath = Path.Combine(libRoot, installFolderName);
                        if (Directory.Exists(installedGameFolderPath)) // JM：未完全完成安装，但是目录已经建立了，可以写入metadata了
                        {
                            Utils.WriteJsonFile(Path.Combine(installedGameFolderPath, @"InstalledMetadata.json"), new InstalledGameMetadata() { PID = this.installingGameMetadata.PID });
                        }

                        var installingGamePID = this.installingGameMetadata.PID;
                        Dictionary<string, InstalledGameMetadata> installedGamesMetadata = library.GetInstalledGames(); // JM：只有这里的metadata是从已安装目录中获取的
                        if (installedGamesMetadata.ContainsKey(installingGamePID)) // JM: 已完成安装
                        {
                            var installInfo = new GameInstallationData()
                            {
                                InstallDirectory = installedGameFolderPath
                            };

                            InvokeOnInstalled(new GameInstalledEventArgs(installInfo));
                            return;
                        }
                    }
                    else
                    {
                        // JM：这里InstallFolderName还未设置为空，那么就没有检查的必要
                        this.library.PlayniteApi.Notifications.Add(new NotificationMessage("InstallFolderNameNotSet", $"Game {installFolderName} InstallFolderName not set!", NotificationType.Info));
                    }

                    await Task.Delay(10000);
                }
            });
        }

    }
}
